//                       .::::.
//                     .::::::::.
//                    :::::::::::
//                 ..:::::::::::'
//              '::::::::::::'
//                .::::::::::
//           '::::::::::::::..
//                ..::::::::::::.
//              ``::::::::::::::::
//               ::::``:::::::::'        .:::.
//              ::::'   ':::::'       .::::::::.
//            .::::'      ::::     .:::::::'::::.
//           .:::'       :::::  .:::::::::' ':::::.
//          .::'        :::::.:::::::::'      ':::::.
//         .::'         ::::::::::::::'         ``::::.
//     ...:::           ::::::::::::'              ``::.
//    ```` ':.          ':::::::::'                  ::::..
//                       '.:::::'                    ':'````..
package com.xw.service;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.NumberUtil;
import com.github.pagehelper.PageHelper;
import com.google.common.base.Splitter;
import com.google.common.collect.Maps;
import com.xw.common.Const;
import com.xw.dao.*;
import com.xw.model.*;
import com.xw.model.sdk.AliPayPCModel;
import com.xw.model.sdk.WXUnifiedOrderMP;
import com.xw.model.sdk.WeChatModel;
import com.xw.service.tool.alipay.AlipayService;
import com.xw.service.tool.wechat.WeChatService;
import com.xw.util.AppUtil;
import com.xw.util.JsonData;
import com.xw.util.WXMPPayUtils;
import com.xw.vo.OrdersItemVo;
import com.xw.vo.OrdersVo;
import com.xw.vo.VideosVo;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.util.Date;
import java.util.List;
import java.util.Map;

@Service
@Transactional(rollbackFor = Exception.class)
public class OrdersServiceImpl implements OrdersService {
    @Resource
    private OrdersMapper ordersMapper;
    @Resource
    private VideosMapper videosMapper;
    @Resource
    private OrdersItemMapper ordersItemMapper;
    @Resource
    private AlipayService alipayService;
    @Resource
    private WeChatService weChatService;
    @Resource
    private UserMapper userMapper;
    @Resource
    private BuyVideosMapper buyVideosMapper;
    @Resource
    private BasicSetMapper basicSetMapper;
    @Resource
    private PlatformBillMapper platformBillMapper;
    @Resource
    private UserBillMapper userBillMapper;

    @Override
    public Map findOrderByUserIdMP(String userId, Integer status, Integer page, Integer limit) {
        if (page != null && limit != null){
            PageHelper.startPage(page,limit,false);
        }
        List<OrdersVo> list = ordersMapper.findOrderByUserIdMP(userId,status);
        return JsonData.success(list);
    }

    @Override
    public Map toBalancePay(String userId, String orderNo, String userPwd) {
        Map map = Maps.newHashMap();
        User user = null;
        //验证是否拉黑
        if (!StringUtils.equals("-1",userId) && StringUtils.isNotBlank(userId)) {
            user = userMapper.selectByPrimaryKey(userId);
            if (user.getUserStatus() == 2) {
                return JsonData.returnMap(811, "您的账号已被锁定");
            }
        }

        //验证该订单的视频有没有被后台删除
        int isdel = ordersItemMapper.findOrdersIsDel(orderNo);
        if (isdel > 0){
            return JsonData.returnMap(500, "该视频已被删除，请勿下单");
        }

        //验证密码是否正确
        if (!StringUtils.equals(user.getUserPwd(),userPwd)){
            return JsonData.returnMap(809,"密码有误");
        }
        //账户余额
        Double balance = user.getBalance();
        //查询订单详情
        Orders model = new Orders();
        model.setOrderNo(orderNo);
        Orders orders = ordersMapper.selectOne(model);

        if (balance.doubleValue() < orders.getPayment().doubleValue()){
            return JsonData.returnMap(822,"您的账号余额不足");
        }

        //扣除余额
        user.setBalance(NumberUtil.sub(user.getBalance(),orders.getPayment()));
        userMapper.updateByPrimaryKeySelective(user);

        //查询该视频名称
        OrdersItem orderItem = new OrdersItem();
        orderItem.setOrderNo(orderNo);
        List<OrdersItem> select = ordersItemMapper.select(orderItem);
        StringBuffer body = new StringBuffer();
        if (select.size() > 0){
            OrdersItem ordersItem = select.get(0);
            body.append(ordersItem.getVideoName());
            //视频大于1，至少有2个就多加个等
            if (select.size() > 1){
                body.append("等");
            }
        }
        //设置支付方式
        orders.setPaymentType(0);
        //订单状态: 0-已取消， 1-待付款，2-已付款(已完成)
        orders.setStatus(2);
        orders.setPaymentTime(new Date());
        ordersMapper.updateByPrimaryKeySelective(orders);

        //更新销量 根据订单查询购买的哪个视频,现在是每个订单只有一个视频
        List<String> videosIdList = ordersItemMapper.findVideosIdByOrdersNo(orderNo);

        if (videosIdList.size() > 0){
            for (String s : videosIdList) {
                Videos videos = videosMapper.selectByPrimaryKey(s);
                videos.setSaleCount(videos.getSaleCount() + 1);
                videosMapper.updateByPrimaryKeySelective(videos);

                //添加购买视频记录
                BuyVideos buyVideos = new BuyVideos();
                buyVideos.setId(AppUtil.uuid());
                buyVideos.setUserId(orders.getUserId());
                buyVideos.setVideosId(s);
                buyVideosMapper.insertSelective(buyVideos);

                /*视频的价格有可能是0，视频价格为0的只能余额支付，需要大于0才会有分成*/
                if (orders.getPayment().doubleValue() > 0) {
                    //付款之后将一部分抽成记录到账单表中
                    BasicSet basicSet = basicSetMapper.selectAll().get(0);
                    //抽成的钱
                    double mul = NumberUtil.mul(basicSet.getPercent(), orders.getPayment());
                    PlatformBill bill = new PlatformBill();
                    bill.setId(AppUtil.uuid());
                    bill.setBillType(0);
                    bill.setMoney(mul);
                    bill.setOrdersNo(orderNo);
                    bill.setCreateTime(new Date());
                    platformBillMapper.insertSelective(bill);

                    //给视频发布者钱，90%
                    double sub = NumberUtil.sub(orders.getPayment(), (Double) mul);
                    String videosUserId = videos.getUserId();
                    User videosUser = userMapper.selectByPrimaryKey(videosUserId);
                    videosUser.setBalance(NumberUtil.add(videosUser.getBalance(), (Double) sub));
                    userMapper.updateByPrimaryKeySelective(videosUser);

                    //添加用户账单
                    UserBill userBill = new UserBill();
                    userBill.setId(AppUtil.uuid());
                    userBill.setUserId(videosUserId);
                    userBill.setBillTitle("视频收入-" + videos.getVideoName());
                    userBill.setBillType(0);
                    userBill.setMoney(sub);
                    userBill.setCreateTime(new Date());
                    userBill.setFromUserId("0");
                    userBill.setFlag(2);
                    //0.未付款 1.已付款
                    userBill.setPayStatus(1);
                    //0.余额 1.支付宝 2.微信
                    userBill.setPayType(0);
                    userBill.setOrdersNo(orderNo);
                    userBillMapper.insertSelective(userBill);
                }
            }
        }
        return JsonData.success(map);
    }

    @Override
    public Map findOrdersByPublishVideoIdJson(String videoId, Integer page, Integer limit) {
        int size = ordersMapper.findOrdersByPublishVideo(videoId).size();
        if (page != null && limit != null){
            PageHelper.startPage(page,limit,false);
        }
        List<OrdersVo> list = ordersMapper.findOrdersByPublishVideo(videoId);
        //查询总金额
        double totalMoney = ordersMapper.findOrdersTotalMoney(videoId);
        Map map = JsonData.returnLayuiMap(list, size);
        map.put("totalMoney",totalMoney);
        return map;
    }

    @Override
    public Map findOrdersByPublishUserId(String userId, Integer page, Integer limit) {
        int size = ordersMapper.findOrdersByPublishUserId(userId).size();
        if (page != null && limit != null){
            PageHelper.startPage(page,limit,false);
        }
        List<OrdersVo> list = ordersMapper.findOrdersByPublishUserId(userId);
        //查询总金额
        double totalMoney = ordersMapper.findTotalMoney(userId);
        Map map = JsonData.returnLayuiMap(list, size);
        map.put("totalMoney",totalMoney);
        return map;
    }

    @Override
    public Map delOrderById(String userId, String ordersId) {
        //验证是否拉黑
        if (!StringUtils.equals("-1",userId) && StringUtils.isNotBlank(userId)) {
            User user = userMapper.selectByPrimaryKey(userId);
            if (user.getUserStatus() == 2) {
                return JsonData.returnMap(811, "您的账号已被锁定");
            }
        }
        Orders orders = new Orders();
        orders.setId(ordersId);
        orders.setIsDel(1);
        int i = ordersMapper.updateByPrimaryKeySelective(orders);
        return JsonData.returnMap(i);
    }

    @Override
    public Map findByWhere(Integer page, Integer limit, String date, Integer ordersStatus,String videoName,String teacherName) {
        String startTime=null;
        String endTime=null;
        if (StringUtils.isNotBlank(date)){
            List<String> strings = Splitter.on(" - ").splitToList(date);
            startTime = strings.get(0);
            endTime = strings.get(1);
        }

        int size = ordersMapper.findByWhere(startTime, endTime, ordersStatus,videoName,teacherName).size();
        if (page != null && limit != null){
            PageHelper.startPage(page,limit,false);
        }

        List<OrdersVo> list = ordersMapper.findByWhere(startTime,endTime,ordersStatus,videoName,teacherName);

        //查询总金额
        double totalMoney = ordersMapper.findWhereByTotalMoney(startTime, endTime, ordersStatus,videoName,teacherName);
        Map map = JsonData.returnLayuiMap(list, size);
        map.put("totalMoney",totalMoney);
        return map;
    }

    @Override
    public Map findOrderDetailByOrdersId(String userId, String ordersId) {
        //验证是否拉黑
        if (!StringUtils.equals("-1",userId) && StringUtils.isNotBlank(userId)) {
            User user = userMapper.selectByPrimaryKey(userId);
            if (user.getUserStatus() == 2) {
                return JsonData.returnMap(811, "您的账号已被锁定");
            }
        }
        Map map = Maps.newHashMap();
        Orders orders = ordersMapper.selectByPrimaryKey(ordersId);
        OrdersItem ordersItem = new OrdersItem();
        ordersItem.setOrderNo(orders.getOrderNo());
        OrdersItem item = ordersItemMapper.selectOne(ordersItem);
        VideosVo videosVo = videosMapper.findByVideoId(item.getVideoId());
        map.put("orders",orders);
        map.put("item",item);
        map.put("videosVo",videosVo);

        return JsonData.success(map);
    }

    @Override
    public Map findOrderByUserId(String userId, Integer status, Integer page, Integer limit) {
        //验证是否拉黑
        if (!StringUtils.equals("-1",userId) && StringUtils.isNotBlank(userId)) {
            User user = userMapper.selectByPrimaryKey(userId);
            if (user.getUserStatus() == 2) {
                return JsonData.returnMap(811, "您的账号已被锁定");
            }
        }
        Map map = Maps.newHashMap();
        Integer totalSize = ordersMapper.findOrderByUserId(userId, status).size();
        if (page != null && limit != null){
            PageHelper.startPage(page,limit,false);
        }
        List<OrdersVo> list = ordersMapper.findOrderByUserId(userId,status);

        for (OrdersVo ordersVo : list) {
            List<OrdersItemVo> voList = ordersItemMapper.findByOrderNo(ordersVo.getOrderNo());
            ordersVo.setList(voList);
        }

        map.put("list",list);
        map.put("totalSize",totalSize);
        return JsonData.success(map);
    }

    @Override
    public Map toPay(HttpServletRequest request, String userId, String orderNo, Integer payType, String openId) throws Exception {
        Map map = Maps.newHashMap();

        //验证是否拉黑
        if (!StringUtils.equals("-1",userId) && StringUtils.isNotBlank(userId)) {
            User user = userMapper.selectByPrimaryKey(userId);
            if (user.getUserStatus() == 2) {
                return JsonData.returnMap(811, "您的账号已被锁定");
            }
        }

        //验证该订单的视频有没有被后台删除
        int isdel = ordersItemMapper.findOrdersIsDel(orderNo);
        if (isdel > 0){
            return JsonData.returnMap(500, "该视频已被删除，请勿下单");
        }

        Orders model = new Orders();
        model.setOrderNo(orderNo);
        Orders orders = ordersMapper.selectOne(model);
        //设置支付方式
        orders.setPaymentType(payType);

        //查询该视频名称
        StringBuffer body = new StringBuffer();
        body.append("购买课程");
//        OrdersItem orderItem = new OrdersItem();
//        orderItem.setOrderNo(orderNo);
//        PageHelper.orderBy("create_time asc");
//        List<OrdersItem> select = ordersItemMapper.select(orderItem);
//        if (select.size() > 0){
//            OrdersItem ordersItem = select.get(0);
//            body.append(ordersItem.getVideoName());
//            //视频大于1，至少有2个就多加个等
//            if (select.size() > 1){
//                body.append("等");
//            }
//        }

        if (payType==1){
            ordersMapper.updateByPrimaryKeySelective(orders);
            //支付宝
            AliPayPCModel aliPayPCModel = new AliPayPCModel();
            aliPayPCModel.setBody(body.toString());
            aliPayPCModel.setSubject("购买视频");
            aliPayPCModel.setOutTradeNo(orderNo);
            //支付宝以元为单位
            aliPayPCModel.setTotalAmount(orders.getPayment().toString());
            aliPayPCModel.setNotifyUrl(Const.WEB_URL+"/aliPayCallBack/payOrders");
            map = alipayService.toPCPay(aliPayPCModel);
        }else if (payType==2){
            ordersMapper.updateByPrimaryKeySelective(orders);
            //微信
            WeChatModel weChatModel = new WeChatModel();
            weChatModel.setBody(body.toString());
            //微信以分为单位
            weChatModel.setTotal_fee((int)(orders.getPayment() * 100));
            weChatModel.setNotify_url(Const.WEB_URL+"/weChatCallBack/payOrders");
            weChatModel.setOut_trade_no(orderNo);
            map = weChatService.toNativePay(weChatModel,request);
        }else if (payType == 3){
            //小程序支付
            WXUnifiedOrderMP mp = new WXUnifiedOrderMP();
            mp.setTotal_fee((int)(orders.getPayment() * 100));
            mp.setBody(body.toString());
            mp.setNotify_url(Const.WEB_URL+"/weChatCallBack/payOrders");
            mp.setOut_trade_no(orderNo);
            mp.setSpbill_create_ip(request.getLocalAddr());
            mp.setOpenid(openId);
            map = WXMPPayUtils.unifiedOrder(mp);
            map.put("timeStamp",new Date());
        }
        return JsonData.success(map);
    }

    @Override
    public Map placeOrder(String userId, String videoId) {
        //验证是否拉黑
        if (!StringUtils.equals("-1",userId) && StringUtils.isNotBlank(userId)) {
            User user = userMapper.selectByPrimaryKey(userId);
            if (user.getUserStatus() == 2) {
                return JsonData.returnMap(811, "您的账号已被锁定");
            }
        }
        //查询该课程是否在订单中，并且是未支付状态
        Orders model = ordersItemMapper.findOrdersByVideoId(userId,videoId);
        if (model != null){
            return JsonData.returnMap(500,"存在未支付的相同课程",model);
        }

        Videos videos = videosMapper.selectByPrimaryKey(videoId);

        //添加订单
        Orders orders = new Orders();
        String orderNo = AppUtil.getOrderCode();
        orders.setId(AppUtil.uuid());
        orders.setOrderNo(orderNo);
        orders.setPayment(videos.getCurrentPrice());
        //0-已取消， 1-未付款，2-已付款
        orders.setStatus(1);
        orders.setCreateTime(new Date());
        orders.setUserId(userId);

        OrdersItem ordersItem = new OrdersItem();
        ordersItem.setId(AppUtil.uuid());
        ordersItem.setOrderNo(orderNo);
        ordersItem.setVideoId(videoId);
        ordersItem.setVideoName(videos.getVideoName());
        ordersItem.setVideoImage(videos.getVideoImg());
        ordersItem.setVideoCurrentPrice(videos.getCurrentPrice());
        ordersItem.setQuantity(1);
        ordersItem.setTotalPrice(videos.getCurrentPrice());
        ordersItem.setCreateTime(new Date());
        //订单未支付过期时间 +24小时
        orders.setOverTime(DateUtil.tomorrow());

        ordersMapper.insertSelective(orders);
        ordersItemMapper.insertSelective(ordersItem);

        Map map = Maps.newHashMap();
        map.put("orders",orders);
        map.put("ordersItem",ordersItem);
        return JsonData.success(map);
    }
}
